/** ***************************************************************************
 * CoffeeFile.hpp
 * 2012 CoffeeParty Ltd.
 * Date Created: 2012-07-21                                  format YYYY-MM-DD
 * Revision Id: $Id$
 ******************************************************************************
 */

#ifndef _COFFEE_FILE_HPP_
#define _COFFEE_FILE_HPP_

#include "CoffeeCommons.hpp"
#include "CoffeeString.hpp"
#include "CoffeeExyst.hpp"
#include "CoffeeTypes.hpp"

class CoffeeIO : public virtual CoffeeExyst
{
public:
    CoffeeIO() { };
    CoffeeIO(c_const_bytep filename, c_const_bytep mode) { };
    ~CoffeeIO() { };

    virtual c_string filename() = 0;

    virtual c_size_t size() const = 0;
    virtual c_size_t read(c_voidp data, c_size_t length) = 0;
    virtual c_size_t write(c_voidp data, c_size_t length) = 0;

    virtual c_byte read_byte() = 0;
    virtual c_byte write_byte(c_byte data) = 0;

    virtual c_size_t pos() const = 0;
    virtual c_bool seek(c_size_t offset, c_bool relative) = 0;
    virtual c_bool isOpen() = 0;
};

class CoffeeFile : public CoffeeIO
{
public:
    CoffeeFile(c_const_bytep filename, c_const_bytep mode = "rb+");
    ~CoffeeFile();

    c_string filename();

    c_size_t size() const;
    c_size_t read(c_voidp data, c_size_t length);
    c_size_t write(c_voidp data, c_size_t length);

    c_byte read_byte();
    c_byte write_byte(c_byte data);

    c_size_t pos() const;
    c_bool seek(c_size_t offset, c_bool relative = false);
    c_bool isOpen();

protected:
    c_bool open(c_const_bytep filename, c_const_bytep mode);
    c_void close();

private:
    c_file_p file;
    c_size_t filelength;
    c_const_string cfilename;
};

class CoffeeMemory : public CoffeeIO
{
public:
    CoffeeMemory(c_voidp data, c_long length, c_const_string &filename, c_bool _on_clean);
    ~CoffeeMemory();

    c_string filename() const;
    c_size_t size() const;
    c_size_t read(c_voidp data, c_size_t length);
    c_size_t write(c_voidp data, c_size_t length);
    c_size_t pos() const;
    c_bool seek(c_size_t offset, c_bool relative = false);

protected:
    c_voidp bufdata;
    c_size_t memlength;
    c_size_t mempos;
    c_const_string cfilename;
    c_bool on_clean;
};


#endif /** _COFFEE_FILE_HPP_ */
